import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
	// Parse the input file using the CSV Parser class
	CSVParser parser = new CSVParser(args[0], false);
	System.out.println("Parsing CSV file...\n");
	TransactionList tlist = parser.parse();
	System.out.println("Done\n");
	//tlist.print();

	Double support = Double.parseDouble(args[1]);
	Double confidence = Double.parseDouble(args[2]);

	System.out.println("Identifying large itemsets...\n");
	ArrayList<ItemsetList> L = apriori(tlist, support);
	System.out.println("Done\n");
	// Consolidate all of the large itemsets into one list
	ItemsetList fullList = new ItemsetList(support, tlist, -1).consolidate(L);
	
	System.out.println("Writing to output file...\n");
	// Output the results to the output file
	printOutputFile(support, confidence, fullList);
	System.out.println("Done\n");
    }

    public static ArrayList<ItemsetList> apriori(TransactionList tlist, Double support){
	// ArrayList L will hold all of the large "k" itemsets, where k is the index
	// of the ArrayList and k + 1 is the number of items in each itemset
	ArrayList<ItemsetList> L = new ArrayList<ItemsetList>();

	// First, get the large 1-itemsets
	L.add(tlist.getLarge1Itemsets(support));

	// Loop through values of k
	for (Integer k = 1; !L.get(k-1).isEmpty(); k++){

	    // Generate the new candidates from L(k-1) using the apriori-gen function and add
	    // the resulting ItemsetList into the ArrayList L
	    L.add(L.get(k - 1).aprioriGen());  

	    // Loop through each transaction
	    for (Transaction t : tlist.getTransactions()){

		// For each transaction, get the candidates that are contained within it
		// and increment their count
		L.get(k).incrementCandidates(t);
	    }

	    // Calculate the support for each item in the list
	    L.get(k).calculateSupport();
	    
	    // Isolate only those itemsets that meet the minimum support
	    L.get(k).prune();
	    //L.get(k).print();
	}
	return L;
    }

    public static void printOutputFile(Double support, Double confidence, ItemsetList fullList){
	FileWriter fstream;
	BufferedWriter out = null;
	try {
	    fstream = new FileWriter("output.txt");
	    out = new BufferedWriter(fstream);
	    out.write(String.format("==Large itemsets (min_sup=%f%%)", support * 100));
	    out.newLine();
	    for (Itemset iset : fullList.getOrderedItems()){
		out.write(iset.toString() + ", ");
		out.write(String.format("%f%%", 100 * iset.getSupport()));
		out.newLine();
	    }

	    out.newLine();
	    out.newLine();
	    out.write(String.format("==High-confidence association rules (min_conf=%f%%)", confidence * 100));
	    out.newLine();
	    fullList.printAssociationRules(confidence, out);
	    out.newLine();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	finally {
	    try {
		out.close();
	    } catch (IOException ioe) {
		ioe.printStackTrace();
	    }
	}
    }
}

